import time,urandom,sys
import world
from util import button,beep
from dataSet import DataSet
from trainer import train

class AppOmt:
	def __init__(self,display,mode=1):
		self.display = display
		# Game mode
		# self.HUMAN = 0
		# self.TRAIN = 1
		# self.AI = 2
		self.mode = mode

		# num of iteration
		self.epoch0 = 200 # human
		self.epoch1 = 500 # train
		self.epoch2 = 200 # AI

		# Creat a game world
		self.world = world.World(display)

		# Creat dataSet
		self.dataSet = DataSet()

	def show(self, epoch):
		self.display.fill(0)

		self.world.show()

		# show game mode
		if(self.mode == 0):
			self.display.text("H",20,0,1)
		elif(self.mode == 2):
			self.display.text("A",20,0,1)
		else:
			self.display.text("T",20,0,1)

		# show current epoch
		self.display.text(str(epoch),40,0,1)

		self.display.show()

	def show_mode(self):
		self.display.fill(0)

		# show game mode
		if(self.mode == 0):
			self.display.text("Human Control",15,30,1)
		elif(self.mode == 1):
			self.display.text("Robot Learning",10,30,1)
		else:
			self.display.text("AI Control",30,30,1)

		self.display.show()
		# sleep
		time.sleep(1)

	def run(self,mode=1):
		self.mode = mode
		if(self.mode == 0): # Human control
			self.run0()
		elif(self.mode == 1): # Robot Learning
			self.run1()
			# finish train, switch to mode 2
			self.display.text("Click to AI ctrl", 0, 20, 1)
			self.display.show()
			while(button.value() == 0): #wait click
				pass
			self.run(2)
		elif(self.mode == 2): # AI control
			self.run2()

	# Human control
	def run0(self):
		self.show_mode()
		for i in range(self.epoch0):
			# world update
			self.world.update()

			# read human input, control the robot
			if(button.value() == 1):
				self.world.robot.jump()

			# refresh screen
			self.show(i)

			# sleep
			time.sleep_ms(10)

	# Robot Learning
	def run1(self):
		self.show_mode()
		for i in range(self.epoch1):
			# world update
			self.world.update()
			# add sample
			if(self.addSample(button.value())==True):
				self.world.robot.n_collisions = 0
				break # end of add samples
			# refresh screen
			self.show(i)
			# sleep
			time.sleep_ms(10)
		# train neuron
		train(self.dataSet,self.world.robot.neuron,0.8)
		self.dataSet.reset()

	def addSample(self, human_command):
		full = False
		if self.world.robot.onGround():
			if(human_command == 1):
				beep()
				self.world.robot.jump()
				full = self.dataSet.add(self.world.robot.distance, self.world.robot.obs_width, 1)
			else:
				if(urandom.getrandbits(8)<80): # p=0.3 as a sample
					full = self.dataSet.add(self.world.robot.distance, self.world.robot.obs_width, 0)
		return full

	# AI control
	def run2(self):
		self.show_mode()
		for i in range(self.epoch2):
			# world update
			self.world.update()

			# AI decision
			self.world.robot.think()

			# refresh screen
			self.show(i)

			# sleep
			time.sleep_ms(10)
		self.display.fill(0)
		self.display.text("Game Over",20,15,1)
		self.display.text("collisions: ",0,30,1)
		self.display.text(str(self.world.robot.n_collisions),100,30,1)
		self.display.text("Click to exit", 10, 45, 1)
		self.display.show()
		while(button.value() == 0): #wait click
			pass

def delAppOmt():
	print("--delte appOmt modules--")
	del(sys.modules['appOmt'])
	del(sys.modules['dataSet'])
	del(sys.modules['ground'])
	del(sys.modules['neuron'])
	del(sys.modules['robot'])
	del(sys.modules['staticObject'])
	del(sys.modules['trainer'])
	del(sys.modules['world'])
